package gui;

import gui.events.CreateTableEvent;
import gui.interfaces.ICreateTableEventListener;
import gui.renderers.DataTypeComboboxRenderer;
import gui.renderers.TableCellListener;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

import controller.InitiliazeController;
import dto.ColumnDTO;
import dto.DatabaseIconDTO;

@SuppressWarnings("serial")
public class PanelCreateTable extends JPanel {
	@SuppressWarnings("rawtypes")
	private List _listeners = new ArrayList();
	private JTextField txtTableName;
	private JTable tblColumns;
	private JComboBox cbbSelectDatabase;

	/**
	 * Create the panel.
	 */
	public PanelCreateTable() {
		setLayout(new BorderLayout(0, 0));

		JPanel panel = new JPanel();
		add(panel, BorderLayout.NORTH);
		panel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

		JLabel lblTableName = new JLabel("Table Name : ");
		panel.add(lblTableName);

		txtTableName = new JTextField();
		panel.add(txtTableName);
		txtTableName.setColumns(25);

		JLabel lblDatabase = new JLabel("Database : ");
		panel.add(lblDatabase);

		// Get all database names from database.
		InitiliazeController initCtrl = null;
		try {
			initCtrl = new InitiliazeController();
		} catch (UnknownHostException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();

		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			JOptionPane.showMessageDialog(this, e1.getMessage());
			return;
		}
		ArrayList<DatabaseIconDTO> dbIcons;
		try {
			dbIcons = initCtrl.getAllDatabaseName();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			JOptionPane.showMessageDialog(this, e1.getMessage());
			return;
		}
		ArrayList<String> dbs = new ArrayList<>();
		for (DatabaseIconDTO info : dbIcons) {
			dbs.add(info.getDatabaseName());
		}
		cbbSelectDatabase = new JComboBox(dbs.toArray(new String[] {}));
		cbbSelectDatabase.setToolTipText("Select database");
		panel.add(cbbSelectDatabase);

		JPanel panel_1 = new JPanel();
		add(panel_1, BorderLayout.CENTER);
		panel_1.setLayout(new BorderLayout(0, 0));

		JScrollPane scrollPane = new JScrollPane();
		panel_1.add(scrollPane);

		tblColumns = new JTable();
		tblColumns.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		tblColumns.setShowVerticalLines(false);
		tblColumns.setFillsViewportHeight(true);
		tblColumns.setModel(new DefaultTableModel(new Object[][] { { null,
				null, null, null, null }, }, new String[] { "", "Column Name",
				"Data Type", "", "" }));

		// tblColumns.setSize(panel_1.getWidth(), panel_1.getHeight());
		tblColumns.getColumnModel().getColumn(0).setPreferredWidth(30);
		tblColumns.getColumnModel().getColumn(1).setPreferredWidth(300);
		tblColumns.getColumnModel().getColumn(2).setPreferredWidth(100);
		tblColumns.setRowHeight(20);

		// These are the combo-box values
		String[] values = new String[] { "Int", "String" };
		int colIndex = 2;
		TableColumn col = tblColumns.getColumnModel().getColumn(colIndex);
		col.setCellEditor(new DataTypeCombobox(values));

		// If the cell should appear like a combo-box in its
		// non-editing state, also set the combo-box renderer
		col.setCellRenderer(new DataTypeComboboxRenderer(values));

		// Set Key listener for 2nd visible column
		Action action = new AbstractAction() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				TableCellListener tcl = (TableCellListener) arg0.getSource();
				if (tcl.getColumn() == 1) {
					// add new row
					DefaultTableModel model = (DefaultTableModel) tblColumns
							.getModel();
					model.insertRow(tcl.getRow() + 1, new Object[] { null,
							null, null });
				}
			}
		};
		@SuppressWarnings("unused")
		TableCellListener tcl = new TableCellListener(tblColumns, action);

		scrollPane.setViewportView(tblColumns);

		JPanel panel_2 = new JPanel();
		add(panel_2, BorderLayout.SOUTH);
		panel_2.setLayout(new BorderLayout(0, 0));

		JPanel panel_3 = new JPanel();
		panel_2.add(panel_3, BorderLayout.NORTH);
		panel_3.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

		JButton btnCreate = new JButton("Create");
		btnCreate.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				fireApplyEvent();
			}
		});
		panel_3.add(btnCreate);

		JButton btnCancel = new JButton("Cancel");
		btnCancel.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseClicked(MouseEvent e) {
				fireCancelEvent();
			}
		});
		panel_3.add(btnCancel);

	}

	public synchronized void addCreateTableEventListener(
			ICreateTableEventListener listener) {
		_listeners.add(listener);
	}

	public synchronized void removeCreateTableEventListener(
			ICreateTableEventListener listener) {
		_listeners.remove(listener);
	}

	public synchronized void fireApplyEvent() {
		ArrayList<ColumnDTO> cols = new ArrayList<>();
		TableModel model = tblColumns.getModel();
		for (int i = 0; i < model.getRowCount(); i++) {
			String colName = (String) model.getValueAt(i, 1);
			String colType = (String) model.getValueAt(i, 2);
			if (colName == null || colType == null) {
				continue;
			}
			cols.add(new ColumnDTO(colName, colType));
		}
		CreateTableEvent event = new CreateTableEvent(this);
		Iterator i = _listeners.iterator();
		while (i.hasNext()) {
			((ICreateTableEventListener) i.next()).apply(event,
					cbbSelectDatabase.getSelectedItem().toString(),
					txtTableName.getText(), cols);
		}
	}

	public synchronized void fireCancelEvent() {
		CreateTableEvent event = new CreateTableEvent(this);
		Iterator i = _listeners.iterator();
		while (i.hasNext()) {
			((ICreateTableEventListener) i.next()).cancel(event);
		}
	}
}
